
#include <linux/module.h>  
#include <linux/kernel.h> 
#include <linux/init.h>  
#include <linux/ioport.h>  
#include <linux/fs.h>  
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/uaccess.h> //from - to user
#include <linux/ioctl.h>
#include <linux/proc_fs.h>
#include <linux/kobject.h>
#include <asm/io.h> //ioremap function
#include <mach/gpio.h>  //request mem region
#include <linux/mm.h> //mmap
#include <mach/at91_pmc.h>
#include <mach/at91sam9_smc.h>
#include <mach/at91sam9_smc.h>
#include <mach/at91sam9263.h>


MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Mateusz Poplawski");

#define EBI1_PHYS_ADDR 0x70000000
#define FPGA_SIZE 0xFFFF
#define __DEBUG__


#define SHIFT_LEFT(x)   	     ((x) << 1)
#define DEVICE_NAME "fpga_dev"

#define FPGA_DRV_IOC_MAGIC  'k'
#define FPGA_DRV_READ_16BIT _IOWR(FPGA_DRV_IOC_MAGIC,  1, data_16)
#define FPGA_DRV_WRITE_16BIT _IOW(FPGA_DRV_IOC_MAGIC,  2,data_16)
#define FPGA_DRV_RESET _IO(FPGA_DRV_IOC_MAGIC,  3)
#define FPGA_DRV_READ_32BIT _IOWR(FPGA_DRV_IOC_MAGIC,  4, data_32)
#define FPGA_DRV_WRITE_32BIT _IOW(FPGA_DRV_IOC_MAGIC,  5,data_32)

static long fpga_drv_ioctl (struct file *filp, unsigned int cmd, unsigned long arg);
static int fpga_drv_open(struct inode *inode, struct file *file);
static int fpga_drv_release(struct inode *inode, struct file *file);
void fpga_vma_open (struct vm_area_struct * area);
void fpga_vma_close (struct vm_area_struct * area);
static int fpga_mmap(struct file *filp, struct vm_area_struct *vma);


typedef struct {
	unsigned short	data;
	unsigned int	address;							
} data_16;


typedef struct {
	unsigned int	data;
	unsigned int	address;							
} data_32;


struct sam9_smc_config {
	/* Setup register */
	u8 ncs_read_setup;
	u8 nrd_setup;
	u8 ncs_write_setup;
	u8 nwe_setup;

	/* Pulse register */
	u8 ncs_read_pulse;
	u8 nrd_pulse;
	u8 ncs_write_pulse;
	u8 nwe_pulse;

	/* Cycle register */
	u16 read_cycle;
	u16 write_cycle;

	/* Mode register */
	u32 mode;
	u8 tdf_cycles:4;
};







struct file_operations fops = {
	.owner =    THIS_MODULE,
	.open = fpga_drv_open,
	.release = fpga_drv_release,
	.unlocked_ioctl =    fpga_drv_ioctl,
	.mmap = fpga_mmap,
};
static struct vm_operations_struct fpga_vm_ops = {
  fpga_vma_open,
  fpga_vma_close,
};



static struct sam9_smc_config smc_config = {
	.ncs_read_setup		= 2,
	.nrd_setup		= 2,
	.ncs_write_setup	= 2,
	.nwe_setup		= 2,

	.ncs_read_pulse		= 3,
	.nrd_pulse		= 3,
	.ncs_write_pulse	= 3,
	.nwe_pulse		= 3,

	.read_cycle		= 5,
	.write_cycle		= 5,

	.mode			= AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_DBW_16 ,
	.tdf_cycles		= 0,
};


static int fpga_init(void);
static void fpga_exit(void);
void sam9_smc_configure(int cs, struct sam9_smc_config * config);
void write16(unsigned int address,  unsigned short val);
void read16(unsigned int address,  unsigned short *val);
void write32(unsigned int address,  unsigned int val);
void read32(unsigned int address,  unsigned int *val);


